<template>
  <div class="role">
    <el-card>
      <el-form inline class="user-form">
        <el-form-item label="职位搜索">
          <el-input  placeholder="请输入搜索的职位关键字" v-model="keyword" ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :disabled="!keyword" @click="search">搜索</el-button>
          <el-button type="default" @click="reset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 表格 -->
    <el-card style="margin: 10px 0;">
      <el-button type="primary" icon="Plus" @click="addRole">添加职位</el-button>
      <el-table border style="margin: 10px 0;" :data="allRole">
        <el-table-column label="#" align="center" type="index"></el-table-column>
        <el-table-column label="ID" align="center" prop="id"></el-table-column>
        <el-table-column label="角色名称" align="center" prop="roleName" show-overflow-tooltip></el-table-column>
        <el-table-column label="创建时间" align="center" prop="createTime" show-overflow-tooltip></el-table-column>
        <el-table-column label="更新时间" align="center" prop="updateTime" show-overflow-tooltip></el-table-column>
        <el-table-column width="300" label="操作" align="center">
          <template #default="{row}">
            <el-button type="primary" size="small" icon="User" @click="setPermission(row)">分配权限</el-button>
            <el-button type="warning" size="small" icon="Edit"  @click="updateRole(row)">编辑</el-button>
            <el-popconfirm @confirm="deleteRole(row)" :title="`你确定要删除${row.roleName}吗?`" width="200">
              <template #reference>
                <el-button type="danger" size="small" icon="Delete" >删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-pagination
        v-model:current-page="pageNo"
        v-model:page-size="pageSize"
        :page-sizes="[10,15,20,25]"
        background
        layout=" prev, pager, next, jumper,->, total, sizes,"
        :total="total"
        @size-change="sizeChange"
        @current-change="getHasRole"
      />
    </el-card>
    <!-- 添加修改职位 -->
    <el-dialog v-model="dialogVisible" :title="roleParams.id?'更新职位':'添加职位'">
      <el-form  ref="formRef" :model="roleParams" :rules="rules">
        <el-form-item label="职位名称" prop="roleName">
          <el-input v-model="roleParams.roleName" placeholder="请输入职位名称"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveRole">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 抽屉 分配用户菜单权限和按钮权限 -->
    <el-drawer v-model="drawer" direction="rtl">
    <template #header>
      <h4>分配权限</h4>
    </template>
    <template #default>
      <!-- 
        node-key: 每个树节点用来作为唯一标识的属性，整棵树应该是唯一的
        default-expanded-keys: 默认展开的节点的 key 的数组
        default-checked-keys: 默认勾选的节点的 key 的数组 
        props: 配置选项
        defaultProps: {
          label: 指定节点标签为节点对象的某个属性值,
          children: 指定子树为节点对象的某个属性值 
        }
    -->
      <el-tree
        ref="tree"
        style="max-width: 600px"
        :data="menuArr"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="selectArr"
        :props="defaultProps"
      />
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="drawer = false">取消</el-button>
        <el-button type="primary" @click="savePermission">确定</el-button>
      </div>
    </template>
  </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, nextTick } from 'vue'
import { reqSetPermission, reqAllMenuList, reqRemoveRole, reqAddOrUpdateRole, reqAllRole } from '@/api/acl/role'
import type { MenuList, RoleData,RoleList } from '@/api/acl/role/type'
import { useLayoutSettingStore } from '@/store/modules/setting';
import { ElMessage } from 'element-plus';

// 分页数据
const pageNo = ref(1)
const pageSize = ref(10)
const total = ref(0)
const keyword = ref('')



// 获取职位
const allRole = ref<RoleList>([])
const getHasRole = async () => {
  const res = await reqAllRole(pageNo.value, pageSize.value, keyword.value)
  if(res.code == 200) {
    total.value = res.data.total
    allRole.value = res.data.records
  }
}

// 搜索
const search = () => {
  getHasRole()
  keyword.value = ''
}

// 重置
const layoutSettingStore = useLayoutSettingStore()
const reset = () => {
  layoutSettingStore.refresh = !layoutSettingStore.refresh
}

const sizeChange = () => {
  pageNo.value = 1
  getHasRole()
}


// 添加修改职位
const roleParams = reactive<RoleData>({
  roleName: ''
})
const dialogVisible = ref(false)
const formRef = ref()
// 校验
const checkRoleName = (rule:any, val:any,callBack:any) => {
  if(val.length >=2 ) {
    callBack()
  } else {
    callBack(new Error('职位名称长度至少要2位~'))
  }
}

const rules = {
  roleName: [
    {required: true,  trigger: 'blur', validator: checkRoleName}
  ]
}

// 添加 修改职位
const addRole = () => {
  // 清空数据
  nextTick(()=>{
    formRef.value.clearValidate('roleName')
  })
  if(roleParams.id) {
    delete roleParams.id
  }
  Object.assign(roleParams, {
    roleName: ''
  })
  dialogVisible.value = true  
}

const updateRole = (row: RoleData) => {
  nextTick(()=>{
    formRef.value.clearValidate('roleName')
  })
  Object.assign(roleParams, row)
  dialogVisible.value = true
}

// 删除
const deleteRole = async (row:RoleData) => {
  const res = await reqRemoveRole(row.id as number)
  if(res.code == 200) {
    ElMessage({
      type: 'success',
      message: '删除成功~'
    })
    if(allRole.value.length <= 1) {
      pageNo.value = pageNo.value -1 <=1?1:pageNo.value -1
    }
    getHasRole()
  } else {
    ElMessage({
      type: 'error',
      message: '删除失败~'
    })
  }
}

// 保存
const saveRole = async () => {
  await formRef.value.validate()
  const res = await reqAddOrUpdateRole(roleParams)
  if(res.code == 200) {
    ElMessage({
      type: 'success',
      message: roleParams.id?'更新成功~':'添加成功~'
    })
    getHasRole()
  } else {
    ElMessage({
      type: 'error',
      message: roleParams.id?'更新失败~':'添加失败~'
    })
  }
  dialogVisible.value = false
}







// 分配权限
const drawer = ref(false)
const menuArr = ref<MenuList>([])
  const defaultProps = {
  children: 'children',
  label: 'name',
}

// 存储4级菜单select为true的id。 如果一级seelct为true,该下面所有菜单都会为true勾选上
// 相反,最底层菜单select为true, 全部选中会带着上层select为true, 所以直接搜集最底层为true的id
const selectArr = ref<number[]>([])
const filterSelectArr = (allData:any,initArr:any) => {
  allData.forEach((item:any) => {
    // select为true且level为4 的才push
    if(item.select && item.level ==4) {
      initArr.push(item.id)
    }
    // 保证children不是空数组
    if(item.children && item.children.length>0) {
      filterSelectArr(item.children, initArr)
    }
  })
  return initArr
}

const setPermission = async (row: RoleData) => {
  drawer.value = true
  // 收集当前要分配权限的职位数据
  Object.assign(roleParams, row)
  // 根据职位获取权限数据
  const res = await reqAllMenuList(roleParams.id as number)
  if(res.code == 200) {
    menuArr.value = res.data
    // 获取四级菜单select为true的id
    selectArr.value = filterSelectArr(menuArr.value,[])
    console.log(selectArr.value)
  }
}

//保存权限
const tree = ref()
const savePermission = async () => {
  const roleId = roleParams.id
  // 获取选中节点id
  const arr = tree.value.getCheckedKeys()
  // 获取半选节点的id
  const arr2 = tree.value.getHalfCheckedKeys()
  const permissionId = [...arr,...arr2]
  const res = await reqSetPermission(roleId as number, permissionId)
  if(res.code == 200) {
    ElMessage({
      type: 'success',
      message: '分配权限成功~'
    })
    drawer.value = false
    // getHasRole()
    //万一修改的事自己的权限 要刷新
    window.location.reload()
  } else {
    ElMessage({
      type: 'error',
      message: '分配权限失败~'
    })
    drawer.value = false
  }
}




onMounted(()=>{
  getHasRole()
})



</script>

<style lang="scss" scoped>
  .role {
    .user-form {
      justify-content: space-between;
      display: flex;
      align-items: center;
      .el-form-item {
        margin-bottom: 0;
      }
    }
  }
</style>
